package com.yuchen.advsdk.weight;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.leo618.zip.IZipCallback;
import com.leo618.zip.ZipManager;
import com.youth.banner.Banner;
import com.yuchen.advsdk.FileDownloader.OkDlManager;
import com.yuchen.advsdk.FileDownloader.OkDlTask;
import com.yuchen.advsdk.R;
import com.yuchen.advsdk.db.ConditionBuilder;
import com.yuchen.advsdk.db.DbUtil;
import com.yuchen.advsdk.eb.EbVideoDownloadedCompleted;
import com.yuchen.advsdk.layout.BannerItem;
import com.yuchen.advsdk.layout.Position;
import com.yuchen.advsdk.layout.VideoItem;
import com.yuchen.advsdk.manager.VideoDownloadManager;
import com.yuchen.advsdk.model.DbVideoFile;
import com.yuchen.advsdk.net.API;
import com.yuchen.advsdk.util.AsyncTaskUtil;
import com.yuchen.advsdk.util.DensityUtil;
import com.yuchen.advsdk.util.FileUtil;
import com.yuchen.advsdk.util.LogUtils;
import com.yuchen.advsdk.weight.marqueeview.HorizontalMarqueeView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class AdvPercentView extends RelativeLayout {

    private static final String TAG = "AdvPercentView";
    private List<HorizontalMarqueeView> marquees = new ArrayList<>();
    private List<Banner> banners = new ArrayList<>();
    private AdVideoView videoView;
    public boolean isPlaying;
    private String layoutMd5;
    public boolean isInit;

    private ImageView setting;

    public enum Model {
        ON_LINE, OFF_LINE, OFF_LINE_ZIP
    }

    private Model model;


    public AdvPercentView(Context context) {
        super(context);
//        init();
        ini();
    }


    public AdvPercentView(Context context, AttributeSet attrs) {
        super(context, attrs);
//        init();
        ini();
    }

    public AdvPercentView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
//        init();
        ini();
    }

    private void ini() {
        EventBus.getDefault().register(this);

        addSettingView();
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
//        return super.dispatchTouchEvent(ev);
        return true;
    }

    public void init() {
        init(Model.ON_LINE);
        Log.d(TAG, "init");


    }

    public void init(Model model) {
        LogUtils.d(TAG, "init : " + model);
        isInit = false;
        this.model = model;
        isPlaying = false;

        if (onInitListener != null) {
            onInitListener.start();
        }
        if (model.equals(Model.OFF_LINE_ZIP)) {
            //离线模式
            if (onInitListener != null) {
                AsyncTaskUtil.run(new AsyncTaskUtil.Task2() {
                    @Override
                    public void taskRun() {
                        VideoDownloadManager.getInstance().init(getContext());
                        VideoDownloadManager.getInstance().checkFile();
                        OkDlManager.getInstance().cancleAllTask();
                    }

                    @Override
                    public void success() {
                        super.success();
                        isInit = true;
                        try {
                            onInitListener.success();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });

            }
        } else {
            //在线模式
            AsyncTaskUtil.run(new AsyncTaskUtil.Task2() {
                @Override
                public void taskRun() {
                    VideoDownloadManager.getInstance().init(getContext());
                    VideoDownloadManager.getInstance().checkFile();
                }

                @Override
                public void success() {
                    super.success();
                    if (onInitListener != null) {
                        isInit = true;
                        try {
                            onInitListener.success();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    VideoDownloadManager.getInstance().resumeAllTask();
                }
            });
        }

    }

    public void onDestory() {
        stop();
        removeAllViews();
        EventBus.getDefault().unregister(this);
    }

    public void parseLayoutZip(final File zipFile) {
        Log.d(TAG, "parseLayoutZip");
        if (onParseLayoutListener != null) {
            onParseLayoutListener.start();
        }
        if (Model.ON_LINE.equals(model)) {
            //判断是否为离线模式
            if (onParseLayoutListener != null) {
                onParseLayoutListener.error("current model is on_line");
            }
        } else if (Model.OFF_LINE_ZIP.equals(model)) {
            try {
                if (!zipFile.exists()) {
                    if (onParseLayoutListener != null) {
                        onParseLayoutListener.error(zipFile.getName() + " is not exists");
                    }
                } else {
                    final long startTime = System.currentTimeMillis();
                    final File layoutFile = new File(zipFile.getParentFile().getAbsolutePath() + "/layout");
                    if (layoutFile.exists()) {
                        layoutFile.delete();
                    }
                    ZipManager.unzip(zipFile.getAbsolutePath(), zipFile.getParentFile().getAbsolutePath(), new IZipCallback() {
                        @Override
                        public void onStart() {

                        }

                        @Override
                        public void onProgress(int percentDone) {

                        }

                        @Override
                        public void onFinish(final boolean success) {
                            Log.d(TAG, "解压耗时：" + (System.currentTimeMillis() - startTime));
                            AsyncTaskUtil.run(new AsyncTaskUtil.Task2() {
                                @Override
                                public void taskRun() {
                                    SystemClock.sleep(10);
                                }

                                @Override
                                public void success() {
                                    super.success();
                                    if (!success) {
                                        if (onParseLayoutListener != null) {
                                            onParseLayoutListener.error(zipFile.getName() + " unzip fail");
                                        }
                                    } else {
                                        File jsonFile = new File(layoutFile.getAbsolutePath() + "/layout.json");
                                        if (!layoutFile.exists()) {
                                            if (onParseLayoutListener != null) {
                                                onParseLayoutListener.error(layoutFile.getAbsolutePath() + " is not exists unzip fail");
                                            }
                                        } else {
                                            try {
                                                Log.d(TAG, "jsonFile.exists() = " + jsonFile.exists());
                                                JSONObject layout = JSON.parseObject(FileUtil.readFile(jsonFile.getAbsolutePath(), 10 * 1024 * 1024));

                                                layout.put("md5", FileUtil.getFileMD5(zipFile));
                                                layout.put("layoutDir", layoutFile.getAbsolutePath());
                                                parseLayout(layout, Model.OFF_LINE_ZIP);
                                            } catch (Exception e) {
                                                Log.d(TAG, "jsonFile.exists() = " + jsonFile.exists());
                                                if (onParseLayoutListener != null) {
                                                    onParseLayoutListener.error(e.getMessage());
                                                }
                                            }

                                        }
                                    }


                                }
                            });


                        }
                    });
                }
            } catch (Exception e) {
                if (onParseLayoutListener != null) {
                    onParseLayoutListener.error(e.getMessage());
                }
            }

        }
    }

    public void parseLayout(String json, Model model) {
        JSONObject layout = JSON.parseObject(json);
        layout.put("md5", FileUtil.getStringMD5(json));
        parseLayout(layout, model);
    }


    private void parseLayout(JSONObject layout, Model model) {
        Log.d(TAG, "parseLayout");
        if (Model.OFF_LINE_ZIP.equals(model)) {

        } else {
            if (onParseLayoutListener != null) {
                onParseLayoutListener.start();
            }
        }
        try {
            removeAllViews();
            marquees.clear();
            banners.clear();
            String layoutDir = layout.getString("layoutDir");
            JSONObject video = layout.getJSONObject("video");
            if (null != video && !video.isEmpty()) {
                videoView = addVideoView(video, layoutDir);
            }
            JSONArray images = layout.getJSONArray("images");
            if (null != images && !images.isEmpty()) {
                for (int i = 0; i < images.size(); i++) {
                    banners.add(addBannerView(images.getJSONObject(i), layoutDir));
                }
            }
            JSONArray ms = layout.getJSONArray("marquees");
            if (null != ms && !ms.isEmpty()) {
                for (int i = 0; i < ms.size(); i++) {
                    marquees.add(addMarqueeView(ms.getJSONObject(i)));
                }
            }
            layoutMd5 = layout.getString("md5");
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (onParseLayoutListener != null) {
                        onParseLayoutListener.success();
                    }
                }
            }, 500);
        } catch (Exception e) {
            e.printStackTrace();
            removeAllViews();
            if (onParseLayoutListener != null) {
                onParseLayoutListener.error(e.getMessage());
            }
        } finally {
            addSettingView();
        }

    }

    public void addSettingView() {
        if (setting == null) {
            setting = new ImageView(getContext());
            long[] arr = new long[]{0, 0, 0};
            setting.setTag(arr);
            setting.setImageResource(R.drawable.icon_screen_setting);
        }
//        setting.setBackgroundColor(getResources().getColor(R.color.colorAccent));
        setting.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "setting click");
                if (!Model.OFF_LINE.equals(model)) {
                    return;
                }
                if (setting.getAlpha() == 1) {
                    if (hideSettingTask != null) {
                        removeCallbacks(hideSettingTask);
                        hideSettingTask = null;
                    }
//                    Intent intent = new Intent(getContext(), LayoutSettingActivity.class);
//                    getContext().startActivity(intent);
//                    setting.setAlpha(0f);

                } else {
                    long[] arr = (long[]) setting.getTag();
                    long[] nowArr = new long[]{System.currentTimeMillis(), arr[0], arr[1]};
                    arr = nowArr;
                    setting.setTag(arr);
                    if (arr[0] - arr[2] < 1000) {
                        setting.setAlpha(1f);
                        if (hideSettingTask != null) {
                            removeCallbacks(hideSettingTask);
                            hideSettingTask = null;
                        }
                        postDelayed(hideSettingTask = new Runnable() {
                            @Override
                            public void run() {
                                setting.setAlpha(0f);
                            }
                        }, 6 * 1000);
                    }
                }
            }
        });
        LayoutParams ps = new LayoutParams(DensityUtil.dip2px(getContext(), 80), DensityUtil.dip2px(getContext(), 80));
        ps.setMargins(DensityUtil.dip2px(getContext(), 10), DensityUtil.dip2px(getContext(), 10), 0, 0);
        setting.setLayoutParams(ps);
        addView(setting);
        setting.setAlpha(0f);
    }

    private Runnable hideSettingTask = null;


    public String getLayoutMd5() {
        return layoutMd5;
    }

    public void setLayoutMd5(String md5) {
        this.layoutMd5 = md5;
    }

    private AdVideoView addVideoView(JSONObject data, String layoutDir) throws Exception {
        final AdVideoView videoView = new AdVideoView(getContext());
        addView(videoView);
        Position position = data.getObject("position", Position.class);
        LayoutParams layoutParams = new RelativeLayout.LayoutParams(position.getWidth(), position.getHeight());
        layoutParams.setMargins(position.getX(), position.getY(), 0, 0);
        videoView.setLayoutParams(layoutParams);
        List<VideoItem> list = JSON.parseArray(data.getString("data"), VideoItem.class);
        List<String> urls = new ArrayList<>();
        List<String> fileMd5List = new ArrayList<>();
        HashMap<String, Object> videoPlayData = new HashMap<>();
        videoPlayData.put("urls", urls);
        videoPlayData.put("md5s", fileMd5List);
        videoPlayData.put("index", 0);
        videoPlayData.put("newData", false);
        for (VideoItem item : list) {
            LogUtils.d(TAG, item.toString());
            if (model.equals(Model.ON_LINE) && (TextUtils.isEmpty(item.getUrl()) || TextUtils.isEmpty(item.getMd5()))) {

            } else {
                if (Model.OFF_LINE_ZIP.equals(model)) {
                    urls.add(layoutDir + item.getUrl());
                    File file = new File(layoutDir + item.getUrl());
                    if (!file.exists()) {
                        throw new Exception("video json url " + file.getAbsolutePath() + " is not exists");
                    }
                } else if (Model.OFF_LINE.equals(model)) {
                    if (!TextUtils.isEmpty(item.getUrl())) {
                        urls.add(item.getUrl());
                        File file = new File(item.getUrl());
                        if (!file.exists()) {
                            throw new Exception("video json url " + file.getAbsolutePath() + " is not exists");
                        }
                    }
                } else if (Model.ON_LINE.equals(model)) {
//                    List<DbVideoFile> dbVideoFiles = DbUtil.find(DbVideoFile.class);
//                KLog.d(dbVideoFiles.toString());
                    item.setUrl(API.newInstance().doRepleaseResourcePath(item.getUrl()));
                    DbVideoFile first = DbUtil.findFirst(DbVideoFile.class, ConditionBuilder.getInstance().start()
                            .addCondition("md5", item.getMd5()).end());
//                KLog.d(first);
                    LogUtils.d(TAG, "" + (first == null ? "true" : first.toString()));
                    fileMd5List.add(item.getMd5());
                    if (first == null) {
//                        VideoDownloadManager.getInstance().addDownload(item.getUrl(), item.getMd5());
                    } else {
                        if (first.getStatus() == OkDlTask.Status.STATUS_SUCCESS) {
                            urls.add(first.getPath());
                        } else {
                            VideoDownloadManager.getInstance().addDownload(item.getUrl(), item.getMd5());
                        }
                    }
                }
            }

        }
        Log.d(TAG, "视频连接：" + urls);
        videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
//                        KLog.d("videoView.onError : " + what + " " + extra);
                        int currentPosition = videoView.getCurrentPosition();
                        HashMap<String, Object> videoPlayData = (HashMap<String, Object>) videoView.getTag();
                        List<String> urls = (List<String>) videoPlayData.get("urls");
                        String url = urls.get((int) videoPlayData.get("index"));

                        if (TextUtils.isEmpty(url)) {

                        } else {
                            try {
                                videoView.setVideoPath(url);
                                videoView.start();
                            } catch (Exception e) {
                                DbUtil.delete(DbVideoFile.class, ConditionBuilder.getInstance()
                                        .start().addCondition("path", url).end());
                                LogUtils.d(TAG, "文件损坏： " + url);
                                setLayoutMd5("");
                                nextVideo();
                            }

                        }
                    }
                }, 500);

                return true;
            }
        });
        videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                mp.reset();
                nextVideo();
            }
        });
        videoView.setTag(videoPlayData);
        return videoView;
    }

    private void nextVideo() {
        HashMap<String, Object> videoPlayData = (HashMap<String, Object>) videoView.getTag();
        int index = (int) videoPlayData.get("index");
        List<String> urls = (List<String>) videoPlayData.get("urls");
        if (index == urls.size() - 1) {
            index = 0;
        } else {
            index++;
        }
        videoPlayData.put("index", index);
        videoView.setVideoPath(urls.get(index));
        if (isPlaying) {
            videoView.start();
        }
    }

    @Subscribe
    public void onVideoDownload(EbVideoDownloadedCompleted eb) {
        if (eb == null) {
            return;
        }
        try {
            if (videoView != null && videoView.getTag() != null) {
                HashMap<String, Object> videoPlayData = (HashMap<String, Object>) videoView.getTag();
                List<String> urls = (List<String>) videoPlayData.get("urls");
                List<String> fileMd5List = (List<String>) videoPlayData.get("md5s");
                if (null != fileMd5List && fileMd5List.contains(eb.getMd5())) {
                    urls.add(eb.getPath());
                    videoView.setTag(videoPlayData);
                    if (videoView.isPlaying()) {

                    } else {
                        if (isPlaying) {
                            videoView.setVideoPath(urls.get(0));
                            videoView.start();
                        }
                    }
                }

            }
        } catch (Exception e) {

        }

    }

    private HorizontalMarqueeView addMarqueeView(JSONObject data) {
        Position position = data.getObject("position", Position.class);
        HorizontalMarqueeView marquee = new HorizontalMarqueeView(getContext());
        LayoutParams layoutParams = new RelativeLayout.LayoutParams(position.getWidth(), position.getHeight());
        layoutParams.setMargins(position.getX(), position.getY(), 0, 0);
        marquee.setLayoutParams(layoutParams);

        addView(marquee);
        marquee.setAnimDuration(30);
        marquee.setAndTextColor(Color.parseColor("#EE0000"));
        marquee.setAndTextSize(50);

        marquee.setTextAnimDirection(HorizontalMarqueeView.Direction.LEFT);

        if (data.keySet().contains("data")) {
            marquee.setMarqueeTv(data.getString("data"));
        }
        JSONObject params = data.getJSONObject("params");
        for (String key : params.keySet()) {
            switch (key) {
                case "duration":
                    marquee.setAnimDuration(params.getIntValue(key));
                    break;
                case "textSize":
                    marquee.setAndTextSize(params.getIntValue(key));
                    break;
                case "textColor":
                    marquee.setAndTextColor(Color.parseColor(params.getString(key)));
                    break;
                case "backgroundColor":
                    marquee.setBackgroundColor(Color.parseColor(params.getString(key)));
                    break;
            }
        }
//        marquee.startAndTextAnim();
        return marquee;
    }

    private Banner addBannerView(JSONObject data, String layoutDir) throws Exception {
        Position position = data.getObject("position", Position.class);
        Banner banner = new Banner(getContext());
        addView(banner);
        List<BannerItem> list = JSON.parseArray(data.getString("data"), BannerItem.class);
        List<String> urls = new ArrayList<>();
        for (BannerItem item : list) {
            if (Model.OFF_LINE_ZIP.equals(model)) {
                urls.add(layoutDir + item.getUrl());
                File file = new File(layoutDir + item.getUrl());
                if (!file.exists()) {
                    throw new Exception("image json url " + file.getAbsolutePath() + " is not exists");
                }
            } else {
                urls.add(API.newInstance().doRepleaseResourcePath(item.getUrl()));
            }
        }
        banner.setImageLoader(new BannerImageLoader());
        banner.setImages(urls);
        LayoutParams layoutParams = new RelativeLayout.LayoutParams(position.getWidth(), position.getHeight());
        layoutParams.setMargins(position.getX(), position.getY(), 0, 0);
        banner.setLayoutParams(layoutParams);

        JSONObject params = data.getJSONObject("params");
        for (String key : params.keySet()) {
            switch (key) {
                case "duration":
                    banner.setDelayTime(params.getIntValue(key) * 1000);
                    break;
            }
        }

        return banner;
    }

    public void onPause() {
        if (isPlaying) {
            stop();
            isPlaying = true;
        }

    }

    public void onResume() {
        if (isPlaying) {
            start();
        }
    }


    public void start() {
        isPlaying = true;
        if (videoView != null) {
            int currentPosition = videoView.getCurrentPosition();
            HashMap<String, Object> videoPlayData = (HashMap<String, Object>) videoView.getTag();
            List<String> urls = (List<String>) videoPlayData.get("urls");
            String url = "";
            if (urls.isEmpty()) {

            } else {
                url = urls.get((int) videoPlayData.get("index"));
            }
            Log.d(TAG, "url:" + url);
            if (TextUtils.isEmpty(url)) {

            } else {
                videoView.setVideoPath(url);
                videoView.start();
            }
        }

        for (Banner banner : banners) {
            banner.start();
        }

        for (HorizontalMarqueeView marqueeView : marquees) {
            marqueeView.startAndTextAnim();
        }
    }

    public void stop() {
        isPlaying = false;
        if (videoView != null) {
            videoView.stopPlayback();
        }
        for (Banner banner : banners) {
            banner.stopAutoPlay();
        }

        for (HorizontalMarqueeView marqueeView : marquees) {
            marqueeView.stopAndTextAnim();
        }
    }

    private OnInitListener onInitListener;

    public OnInitListener getOnInitListener() {
        return onInitListener;
    }

    public void setOnInitListener(OnInitListener onInitListener) {
        this.onInitListener = onInitListener;
    }

    public interface OnInitListener {
        void start();

        void success();
    }

    public OnParseLayoutListener onParseLayoutListener;

    public OnParseLayoutListener getOnParseLayoutListener() {
        return onParseLayoutListener;
    }

    public void setOnParseLayoutListener(OnParseLayoutListener onParseLayoutListener) {
        this.onParseLayoutListener = onParseLayoutListener;
    }

    public interface OnParseLayoutListener {
        void start();

        void success();

        void error(String msg);
    }

}
